/*
 * Copyright (c) 2024 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#include <arch/generic_timers.h>
#include <tools/macros.h>
#include <core/dprintf.h>

#define MRS_CNTFRQ_EL0(value) asm volatile("mrs %0,CNTFRQ_EL0\n\t" : "=r"(value))
#define PT_SET_NEXT(us_time, tick_to_time)                 \
    asm volatile("mul x1,%0,%1\n\t"                        \
                 "msr CNTP_TVAL_EL0,x1 \n\t"               \
                 "mov x0,#0x01\n\t"                        \
                 "msr cntp_ctl_el0,x0\n\t" ::"r"(us_time), \
                 "r"(tick_to_time))

uint32_t timer_frequency;
uint64_t boot_start_time, boot_end_time;
void gpt_init(void)
{
    pt_enable_int();
    MRS_CNTFRQ_EL0(timer_frequency);
    dprintf("current timer frequency:%d HZ\n", timer_frequency);
    (void)pt_set_next(1000);
}

void boottime_calculate(void)
{
    MRS_CNTPCT_EL0(boot_end_time);
    uint64_t boot_time_diff = (boot_end_time - boot_start_time) * 1000U / timer_frequency;
    dprintf("boot time cost:%ld MS\n", boot_time_diff);
}
uint32_t pt_set_next(uint64_t us_time)
{
    uint32_t reserve      = pt_get_left();
    uint64_t tick_to_time = timer_frequency / 1000000U;
    if (0UL == us_time) {
        pt_disable();
    } else {
        PT_SET_NEXT(us_time, tick_to_time);
    }
    return reserve;
}
